home *** CD-ROM | disk | FTP | other *** search
/ ASME's Mechanical Engine…ing Toolkit 1997 December / ASME's Mechanical Engineering Toolkit 1997 December.iso / c_lang / z150_src.lzh / MISC.C < prev    next >
Encoding:
C/C++ Source or Header  |  1987-07-12  |  9.8 KB  |  387 lines

  1. #ifndef LINT
  2. /* @(#) misc.c 1.7 87/05/03 15:59:33 */
  3. static char sccsid[]="@(#) misc.c 1.7 87/05/03 15:59:33";
  4. #endif /* LINT */
  5.  
  6. /*
  7. Copyright (C) 1986, 1987 Rahul Dhesi -- All rights reserved
  8. */
  9. #include "options.h"
  10. /* Miscellaneous functions needed by Zoo but not by Ooz */
  11.  
  12. #include "zoo.h"
  13. #include <stdio.h>
  14. #include "various.h"
  15.  
  16. #include "errors.i"
  17. #include "zoofns.h"
  18. #ifndef NOSIGNAL
  19. #include <signal.h>
  20. #endif
  21.  
  22. #ifdef NEEDCTYP
  23. #include <ctype.h>
  24. #endif
  25.  
  26. /*
  27. calc_ofs() is given a string that (supposedly) begins with a string
  28. of digits.  It returns a corresponding numeric value.  If no such
  29. string, it returns zero.
  30. */
  31. long calc_ofs(str)
  32. char *str;
  33. {
  34.    long retval;
  35.    int status;
  36.    char *p;
  37.    retval = 0L;
  38.    p = str; /* save for error message */
  39.    while (isdigit(*str)) {
  40.       retval = retval * 10L + (*str-'0');
  41.       str++;
  42.    }
  43.    if (*str != '\0')
  44.       prterror ('f', "Invalid number %s\n", p);
  45.    return (retval);
  46. }
  47.  
  48. /*
  49. choosefname() decides which filename to use.  If a long filename is present,
  50. and if the syntax is that of UNIX, MS-DOS or the portable form, we use it;
  51. else we use the short filename. 
  52. */
  53.  
  54. char *choosefname(direntry)
  55. struct direntry *direntry;
  56. {
  57.    char *retptr;                 /* pointer to name that we will return */
  58.    switch (direntry->system_id) {
  59.       case SYSID_NIX:
  60.       case SYSID_PORTABLE:
  61.       case SYSID_MS:
  62.          retptr = (direntry->namlen > 0) ? direntry->lfname : direntry->fname;
  63.          break;
  64.       default:
  65.          retptr = direntry->fname;
  66.          break;
  67.    }
  68.    return (retptr);
  69. } /* choosefname() */
  70.  
  71. /* 
  72. combine() combines a directory name and a filename, making sure the
  73. two are separated by a path separator 
  74. */
  75. char *combine(result, dirname, fname)
  76. char result[], *dirname, *fname;
  77. {
  78.    *result = '\0';
  79.    if (*dirname != '\0') {
  80.       strcpy(result, dirname);
  81.       if (*lastptr(result) != *PATH_CH)
  82.          strcat(result, PATH_CH);
  83.    }
  84.    strcat(result, fname);
  85.    return (result);
  86. }
  87.  
  88. /*
  89. fullpath() accepts a pointer to a directory entry and returns the
  90. combined directory name + filename.  The long filename is used
  91. if available, else the short filename is used.
  92. */
  93. char *fullpath (direntry)
  94. struct direntry *direntry;
  95. {
  96.     static char result[PATHSIZE];
  97.     combine (result,
  98.                 direntry->dirlen > 0 ? direntry->dirname : "", 
  99.                 (direntry->namlen > 0) ? direntry->lfname : direntry->fname
  100.               );
  101.     return (result);
  102. }
  103.  
  104. /* 
  105. ver_too_high returns true if version of provided archive header is
  106. too high for us to manipulate archive 
  107. */
  108.  
  109. int ver_too_high (header)
  110. struct zoo_header *header;
  111. {
  112.    return (header->major_ver > MAJOR_VER ||
  113.             (header->major_ver == MAJOR_VER &&
  114.              header->minor_ver > MINOR_VER));
  115. }
  116.  
  117. /* 
  118. rwheader() reads archive header, checks consistency, makes sure its
  119. version number is not too high, updates it if too low, and seeks to
  120. beginning of first directory entry 
  121. */
  122.  
  123. rwheader (header, zoo_file)
  124. register struct zoo_header *header;
  125. FILE *zoo_file;
  126. {
  127.  
  128.    frd_zooh (header, zoo_file);
  129.  
  130.    if ((header->zoo_start + header->zoo_minus) != 0L)
  131.       prterror ('f', failed_consistency);
  132.    if (ver_too_high (header))
  133.       prterror ('f', wrong_version, header->major_ver, header->minor_ver);
  134.  
  135.    /* We reach here if the archive version is not too high.  Now, if it
  136.    isn't the same as ours, we bring it up to ours so the modified archive 
  137.    will be safe from previous versions of Zoo */
  138.  
  139.    if (header->major_ver != MAJOR_VER || header->minor_ver != MINOR_VER) {
  140.       header->major_ver = MAJOR_VER;
  141.       header->minor_ver = MINOR_VER;
  142.       fseek (zoo_file, 0L, 0);            /* seek to beginning */
  143.       fwr_zooh (header, zoo_file);
  144.    }
  145.    fseek (zoo_file, header->zoo_start, 0); /* seek to where data begins */
  146. } /* rwheader */
  147.  
  148. /*
  149. writedir() write a directory entry with keyboard interrupt disabled
  150. */
  151. void writedir (direntry, zoo_file)
  152. struct direntry *direntry;
  153. FILE *zoo_file;
  154. {
  155. #ifndef NOSIGNAL  
  156.    int (*oldsignal)();
  157.    oldsignal = signal (SIGINT, SIG_IGN);
  158. #endif
  159.    if (fwr_dir (direntry, zoo_file) == -1)
  160.       prterror ('f', disk_full);
  161. #ifndef NOSIGNAL
  162.    signal (SIGINT, oldsignal);
  163. #endif
  164. }
  165.  
  166. /* 
  167. readdir() reads a directory entry from an archive.  If the directory
  168. entry is invalid and if fail is 1, it causes a fatal error;
  169. else it returns.  Return value is 0 if no error else -1;
  170. */
  171.  
  172. int readdir (direntry, zoo_file, fail)    /* read directory entry */
  173. register struct direntry *direntry;
  174. FILE *zoo_file;
  175. int fail;                              /* 0 -> return, 1 -> abort on error */
  176. {
  177.    if (frd_dir (direntry, zoo_file) < 0) {
  178.       if (fail)
  179.          prterror ('f', bad_directory);
  180.       else
  181.          return (-1);
  182.    }
  183.    if (direntry->zoo_tag != ZOO_TAG) {
  184.       if (fail)
  185.          prterror ('f', bad_directory);
  186.       else
  187.          return (-1);
  188.    }
  189.    return (0);
  190. }
  191.  
  192. /* use pointer version below */
  193. #ifdef COMMENT
  194. /* instr() searches a string for a substring */
  195. instr (s, t)      /* return index of string t in string s, -1 if none */
  196. char s[], t[];    /*  .. from K&R page 67 */
  197. {
  198.    int i;
  199.    register int j, k;
  200.    for (i = 0; s[i] != '\0'; i++) {
  201.       for (j = i, k = 0; t[k] != '\0' && s[j]==t[k]; j++, k++)
  202.          ;
  203.       if (t[k] == '\0')
  204.          return (i);
  205.    }
  206.    return (-1);
  207. }
  208. #endif COMMENT
  209.  
  210. /* instr() searches a string for a substring */
  211. /* from J. Brian Waters */
  212. int instr (s, t)           /* return the position of t in s, -1 if none */
  213. char *s, *t;                /*  a pointer version of K&R index function p.67 */
  214. {               /* renamed to instr() to avoid conflicts with C RTL - JBW */
  215.  
  216.    register char *i, *j, *k;
  217.  
  218.    for (i = s; *i; i++) {
  219.       for (j = i, k = t; (*k) && (*j++ == *k); k++)
  220.          ;
  221.        if (!*k)
  222.          return ((int) (i - s));
  223.    }
  224.    return(-1);
  225. }
  226.  
  227. /* cfactor() calculates the compression factor given a directory entry */
  228. int cfactor (org_size, size_now)
  229. long org_size, size_now;
  230. {
  231.    register int size_factor;
  232.    if ((unsigned long) org_size > 1000000) { /* avoid later overflow */
  233.       org_size = (unsigned long) org_size / 1024;
  234.       size_now = (unsigned long) size_now / 1024;
  235.    }
  236.    if (org_size == 0)         /* avoid division by zero */
  237.       size_factor = 0;
  238.    else {
  239.       size_factor = 
  240.          (
  241.             (1000 * 
  242.                ((unsigned long) org_size - (unsigned long) size_now)
  243.             ) / org_size + 5
  244.          ) / 10;
  245.    }
  246.    return (size_factor);
  247. }
  248.  
  249. #ifndef STRDUP
  250. /***********
  251. strdup() duplicates a string using dynamic memory.
  252. */
  253.  
  254. char *strdup (str)
  255. register char *str;
  256. {
  257.    return (strcpy (emalloc (strlen(str)+1), str));
  258. }
  259. #endif /* STRDUP */
  260.  
  261. /**************
  262. cmpnum() compares two pairs of unsigned integers and returns a negative,
  263. zero, or positive value as the comparison yields less than, equal, or
  264. greater than result.  Each pair of unsigned integers is considered to be the
  265. more significant and the less significant half of a longer unsigned number.
  266.  
  267. Note:  cmpnum is used to compare dates and times.
  268. */
  269.  
  270. int cmpnum (hi1, lo1, hi2, lo2)
  271. register unsigned int hi1, hi2;
  272. unsigned int lo1, lo2;
  273. {
  274.    if (hi1 != hi2)
  275.       return ((int) hi1 - hi2);
  276.    else
  277.       return ((int) lo1 - lo2);
  278. }
  279.  
  280. /*******************/
  281. /* writenull() */
  282. /* writes a null directory entry to the archive whose handle is supplied */
  283. void writenull(handle, length)
  284. int handle, length;
  285. {
  286. #ifndef NOSIGNAL
  287.    int (*oldsignal)();
  288. #endif
  289.    struct direntry newentry;
  290.    memset ((char *) &newentry, 0, sizeof (newentry));
  291.    newentry.zoo_tag = ZOO_TAG;
  292.    newentry.type = 2;
  293.    /* Force entry to be the required length plus possibly 2 stray bytes
  294.    by dividing up the needed padding into dirlen and namlen. */
  295.    if (length > SIZ_DIRL)
  296.       newentry.dirlen = newentry.namlen = (length-SIZ_DIRL)/2 + 2;
  297.    else
  298.       newentry.dirlen = newentry.namlen = 0;
  299. #ifndef NOSIGNAL
  300.    oldsignal = signal (SIGINT, SIG_IGN);
  301. #endif
  302.    if (wr_dir (&newentry, handle) == -1)
  303.       prterror ('f', disk_full);
  304. #ifndef NOSIGNAL
  305.    signal (SIGINT, oldsignal);
  306. #endif
  307. }
  308.  
  309. #ifdef FORCESLASH
  310. /*******************/
  311. /*
  312. fixslash() changes all "\" characters in the supplied string to "/".
  313. */
  314.  
  315. void fixslash (str)
  316. char *str;
  317. {
  318.    register char *p;
  319.    for (p = str; *p != '\0'; p++)
  320.       if (*p == '\\')
  321.          *p = '/';
  322. }
  323. #endif /* FORCESLASH */
  324.  
  325. /* Currently using portable directory I/O for MSC also */
  326. #ifdef COMMENT
  327. #ifndef PORTABLE  
  328. /* portable implementations are elsewhere */
  329. /***********************
  330. Function fwr_dir() writes a directory entry to a FILE.  Return value is -1 on
  331. error, else 0.
  332. */
  333. int fwr_dir(direntry, zoo_file)
  334. struct direntry *direntry;
  335. FILE *zoo_file;
  336. {
  337.    if (fwrite ((char *) direntry, SIZ_DIR, 1, zoo_file) != 1)
  338.       return (-1);
  339.    else
  340.       return (0);
  341. }
  342.  
  343. /***********************
  344. Function wr_dir() writes a directory entry to a handle.  Return value is -1
  345. on error else 0.
  346. */
  347. int wr_dir(direntry, zoo_han)
  348. struct direntry *direntry;
  349. int zoo_han;
  350. {
  351.    if (write (zoo_han, (char *) direntry, SIZ_DIR) != SIZ_DIR)
  352.       return (-1);
  353.    else
  354.       return (0);
  355. }
  356.  
  357. /***********************
  358. Function wr_zooh() writes an archive header to a handle.  Return value -1 if
  359. error else 0.
  360. */
  361. int wr_zooh(zoo_header, zoo_han)
  362. struct zoo_header *zoo_header;
  363. int zoo_han;
  364. {
  365.    if (write (zoo_han, (char *) zoo_header, SIZ_ZOOH) != SIZ_ZOOH)
  366.       return (-1);
  367.    else
  368.       return (0);
  369. }
  370.  
  371. /***********************
  372. Function fwr_zooh() writes an archive header to a FILE.  Return value is -1
  373. if error else 0.
  374. */
  375. int fwr_zooh(zoo_header, zoo_file)
  376. struct zoo_header *zoo_header;
  377. FILE *zoo_file;
  378. {
  379.    if (fwrite ((char *) zoo_header, SIZ_ZOOH, 1, zoo_file) != 1)
  380.       return (-1);
  381.    else
  382.       return (0);
  383. }
  384. #endif /* end of not PORTABLE */
  385. #endif /* COMMENT */
  386.  
  387.